﻿#pragma once

#include <functional>
#include <limits>
#include <QList>
#include <QHash>
#include <QString>
#include <QVector>
#include <vector>
#include "application/pathfinding/multi_agent_solver.h"

namespace application {
namespace pathfinding {

struct WaitConstraint {
    int awaitedAgv{0};
    int waiterAgv{0};
    QString unlockFrom;
    QString unlockTo;
    int waiterStationIndex{0};
};

enum class TemporalEventType {
    LocationEntry,
    SafetyDepart,
    SafetyArrive,
};

struct TemporalEvent {
    int id{0};
    int agvNumber{0};
    QString stationId;
    TemporalEventType type{TemporalEventType::LocationEntry};
    int routeIndex{0};
};

enum class TemporalConstraintType {
    IntraAgent,
    Safety,
    InterAgent,
};

struct TemporalConstraint {
    int fromEventId{0};
    int toEventId{0};
    TemporalConstraintType type{TemporalConstraintType::IntraAgent};
    double lowerBound{0.0};
    double upperBound{std::numeric_limits<double>::infinity()};
};

struct TemporalSchedule {
    QHash<int, double> eventTimes;
};

struct TemporalGraphResult {
    QHash<int, QList<QList<QString>>> segmentsByAgv;
    QHash<QString, int> specialStationWhiteList;
    QList<WaitConstraint> waitConstraints;
    QVector<TemporalEvent> events;
    QVector<TemporalConstraint> constraints;
    TemporalSchedule schedule;
};

struct TemporalGraphBuildConfig {
    std::function<double(const QString&, const QString&)> distanceProvider;
    double maxSpeed{1.0};
    double safetyDistance{0.0};
};

class TemporalGraph {
public:
    TemporalGraph() = default;
    ~TemporalGraph() = default;

    // Build a temporal precedence graph and derive per-agent execution segments
    TemporalGraphResult build(const std::vector<AgentPlan>& plans,
                              const TemporalGraphBuildConfig& config = TemporalGraphBuildConfig{});
};

} // namespace pathfinding
} // namespace application
